


#ifndef _SYS_USW_ACL_EXTRACT_H
#define _SYS_USW_ACL_EXTRACT_H

#ifdef __cplusplus
extern "C" {
#endif

#define STS_ACL_EXIT() goto exit
#define STS_ACL_FUNC_ENTER(lchip)  int32 ret = CTC_E_NONE;
#define STS_ACL_FUNC_EXIT()  return ret;
#define STS_ACL_FUNC_VAL_IS(_rv)  (ret == (_rv))
#define STS_ACL_SUCCESS(_expr) ((_expr) >= 0)
#define STS_ACL_FAILURE(_expr) ((_expr) < 0)
#define STS_ACL_FUNC_ERR()  STS_ACL_FAILURE(ret)


#define STS_ACL_NULL_CHECK(_ptr, _rv)   \
    do {                                \
        if ((_ptr) == NULL) {           \
            ret = _rv;                  \
            STS_ACL_EXIT();             \
        }                               \
    } while (0)


#define STS_ACL_RETURN_VAL_EXIT(_expr)  \
    do {                                \
        ret = _expr;                    \
        STS_ACL_EXIT();                 \
    } while (0)

#define STS_ACL_IF_ERR_EXIT(_expr)      \
    do {                                \
        int32 _rv = _expr;              \
        if (STS_ACL_FAILURE(_rv)) {     \
            SYS_ACL_EXT_DBG("  line:%u, func:%s()\n", __LINE__, __FUNCTION__);\
            ret = _rv;                  \
            STS_ACL_EXIT();             \
        }                               \
    } while(0)



#define _STS_ACL_ALLOC(_ptr, _sz)                      \
    do {                                                \
        if ((_ptr) == NULL) {                           \
            (_ptr) = mem_malloc(MEM_ACL_MODULE, _sz);              \
        } else {                                        \
            STS_ACL_EXIT();                                 \
        }                                               \
    } while (0)



#define SYS_ACL_ALLOC(_ptr, _sz)                   \
            do                                         \
            {                                          \
                _STS_ACL_ALLOC(_ptr, _sz);            \
                STS_ACL_NULL_CHECK(_ptr, CTC_E_NO_MEMORY);    \
                sal_memset(_ptr, 0, _sz);              \
            } while(0)


#define STS_ACL_FREE(_ptr)                          \
    do {                                        \
        if ((_ptr) != NULL) {                   \
            mem_free(_ptr);           \
            (_ptr) = NULL;                      \
        }                                       \
    } while (0)

/*
CTC_FIELD_KEY_TCP_OPTIONS  --udf cam key
CTC_FIELD_KEY_UDF_ENTRY_VALID --udf cam key
CTC_FIELD_KEY_HASH_SEL_ID  -- hash key
CTC_FIELD_KEY_HASH_VALID   -- hash key
CTC_FIELD_KEY_CUSTOMER_ID -- scl
CTC_FIELD_KEY_GEM_PORT --egress acl
CTC_FIELD_KEY_VLAN_XLATE_HIT --egress acl
CTC_FIELD_KEY_WLAN_RADIO_MAC  --not support
CTC_FIELD_KEY_WLAN_RADIO_ID   --not support
CTC_FIELD_KEY_WLAN_CTL_PKT    --not support
CTC_FIELD_KEY_DOT1AE_UNKNOW_PKT --not support
CTC_FIELD_KEY_IS_ESADI
CTC_FIELD_KEY_IS_TRILL_CHANNEL
CTC_FIELD_KEY_TRILL_INNER_VLANID
CTC_FIELD_KEY_TRILL_INNER_VLANID_VALID
CTC_FIELD_KEY_TRILL_KEY_TYPE
CTC_FIELD_KEY_TRILL_LENGTH
CTC_FIELD_KEY_TRILL_MULTIHOP
CTC_FIELD_KEY_IS_Y1731_OAM --l4type/l4UserType
*/

typedef enum sys_acl_kext_ctrl_sel_e {
    /* Selector disabled. */
    SYS_ACL_KEXT_CTRL_SEL_DISABLE            = 0,
    SYS_ACL_KEXT_CTRL_SEL_START              = 1,
    SYS_ACL_KEXT_CTRL_SEL_AUX_TAG_A          = 1,
    SYS_ACL_KEXT_CTRL_SEL_LTID0,
    SYS_ACL_KEXT_CTRL_SEL_LTID1,
    SYS_ACL_KEXT_CTRL_SEL_LTID2,
    SYS_ACL_KEXT_CTRL_SEL_ARP_A,
    SYS_ACL_KEXT_CTRL_SEL_ARP_B,
    SYS_ACL_KEXT_CTRL_SEL_ARP_C,
    SYS_ACL_KEXT_CTRL_SEL_ARP_D,
    SYS_ACL_KEXT_CTRL_SEL_CLASSID_A,    /* ltid ad cid a */
    SYS_ACL_KEXT_CTRL_SEL_CLASSID_B,    /* ltid ad cid b */
    SYS_ACL_KEXT_CTRL_SEL_CLASSID_C,    /* ltid ad cid c */
    SYS_ACL_KEXT_CTRL_SEL_CLASSID_D,    /* ltid ad cid d */
    SYS_ACL_KEXT_CTRL_SEL_VNI_SHARE,
    SYS_ACL_KEXT_CTRL_SEL_SRC_A,
    SYS_ACL_KEXT_CTRL_SEL_UDF_A,
    SYS_ACL_KEXT_CTRL_SEL_UDF_B,
    SYS_ACL_KEXT_CTRL_SEL_FS_1,     /*src info 1*/
    SYS_ACL_KEXT_CTRL_SEL_MAX,
    SYS_ACL_KEXT_CTRL_SEL_MULTIPLEXER,
    SYS_ACL_KEXT_CTRL_SEL_COUNT
} sys_acl_kext_ctrl_sel_t;

typedef enum sys_acl_kext_xdata_sel_e{
    SYS_ACL_KEXT_XDATA_SEL_DW0,
    SYS_ACL_KEXT_XDATA_SEL_DW1,
    SYS_ACL_KEXT_XDATA_SEL_W0,
    SYS_ACL_KEXT_XDATA_SEL_W1,
    SYS_ACL_KEXT_XDATA_SEL_W2,
    SYS_ACL_KEXT_XDATA_SEL_W3,
    SYS_ACL_KEXT_XDATA_SEL_B0,
    SYS_ACL_KEXT_XDATA_SEL_B1,
    SYS_ACL_KEXT_XDATA_SEL_B2,
    SYS_ACL_KEXT_XDATA_SEL_B3,
    SYS_ACL_KEXT_XDATA_SEL_MAX
}sys_acl_kext_xdata_sel_t;

#define SYS_ACL_KEXT_LEVEL_COUNT 5
#define SYS_ACL_KEXT_FINFO_COUNT (1024)
#define SYS_ACL_KFIELD_MAX_CHUNKS 32
#define SYS_ACL_KFIELD_BITMAP_MAX_WORDS 12
#define SYS_ACL_FIELD_BITMAP_MAX_WORDS  12
#define SYS_ACL_KFIELD_F_USE_FINFO_NEW     (1 << 0)
#define SYS_ACL_KFIELD_F_USE_L2_EXT_GRAN16 (1 << 1)
#define SYS_ACL_KFIELD_F_USE_L2_EXT_GRAN8  (1 << 2)
#define SYS_ACL_FIELD_OFFSETS_MAX 128
#define SYS_ACL_ENTRY_PARTS_MAX 3
#define SYS_ACL_PRESEL_NUM 4
#define SYS_ACL_MAX_ENTRY_WIDTH 4
#define SYS_ACL_KFIELD_OFFSETS_MAX 64  /*max parts for key field split*/
#define SYS_ACL_FK_SPAN_MASK 0xF

#define SYS_ACL_EXT_L1_E32_MAX  4
#define SYS_ACL_EXT_L1_E16_MAX  10
#define SYS_ACL_EXT_L1_E8_MAX   8
#define SYS_ACL_EXT_L1_E4_MAX   10
#define SYS_ACL_EXT_L1_E2_MAX   8
#define SYS_ACL_EXT_L2_E16_MAX  10
#define SYS_ACL_EXT_L3_E4_MAX   21
#define SYS_ACL_EXT_L3_E2_MAX   5
#define SYS_ACL_EXT_L3_E1_MAX   2

/*extract selector*/
typedef struct sys_acl_ext_sel_s {
    int8 l1_e32_sel[SYS_ACL_EXT_L1_E32_MAX];    /* 4    of extract 1 from 24 */
    int8 l1_e16_sel[SYS_ACL_EXT_L1_E16_MAX];    /* 10   of extract 1 from 24 */
    int8 l1_e8_sel[SYS_ACL_EXT_L1_E8_MAX];      /* 8    of extract 1 from 15 */
    int8 l1_e4_sel[SYS_ACL_EXT_L1_E4_MAX];      /* 10   of extract 1 from 15 */
    int8 l1_e2_sel[SYS_ACL_EXT_L1_E2_MAX];      /* 8    of extract 1 from 22 */
    int8 l2_e16_sel[SYS_ACL_EXT_L2_E16_MAX];    /* 10   of extract 1 from 18 */
    int8 l3_e4_sel[SYS_ACL_EXT_L3_E4_MAX];      /* 21   of extract 1 from 54 */
    int8 l3_e2_sel[SYS_ACL_EXT_L3_E2_MAX];      /* 5    of extract 1 from 108 */
    int16 l3_e1_sel[SYS_ACL_EXT_L3_E1_MAX];      /* 2    of extract 1 from 216 */
    int8 sel_ctl[SYS_ACL_KEXT_CTRL_SEL_MAX];
} sys_acl_ext_sel_t;


typedef struct sys_acl_field_bitmap_s
{
    uint32 field;
    uint32 bitmap[SYS_ACL_FIELD_BITMAP_MAX_WORDS];
    struct sys_acl_field_bitmap_s *next;
}
sys_acl_field_bitmap_t;


typedef struct sys_acl_field_offset_info_s {
    uint8       num_offsets;
    uint16      offset[SYS_ACL_FIELD_OFFSETS_MAX];
    uint8       width[SYS_ACL_FIELD_OFFSETS_MAX];
} sys_acl_field_offset_info_t;

typedef struct sys_acl_group_field_offset_info_s {
    uint32 *qid_arr;
    sys_acl_field_offset_info_t *offset_arr;
    uint16  size;       /*key field num include ltid*/

} sys_acl_group_field_offset_info_t;


typedef struct sys_acl_keygen_pkt_type_db_s
{
    uint8 l2_type;
    uint8 l3_type;
    uint8 l4_type;
}
sys_acl_keygen_pkt_type_db_t;

#define SYS_ACL_KEYGEN_ENTRY_PARTS_MAX 4

typedef enum sys_acl_keygen_mode_e {
    SYS_ACL_KEYGEN_MODE_SINGLE = 0,
    SYS_ACL_KEYGEN_MODE_DOUBLE = 1,
    SYS_ACL_KEYGEN_MODE_TRIPLE = 2,
    SYS_ACL_KEYGEN_MODE_COUNT = 3
} sys_acl_keygen_mode_t;

typedef enum sys_acl_kext_f_half_flag_e {
    SYS_ACL_KEXT_F_HALF_NONE = 0,
    SYS_ACL_KEXT_F_HALF_LOW  = 1,
    SYS_ACL_KEXT_F_HALF_HIGH = 2,
    SYS_ACL_KEXT_F_HALF_TOTAL  = SYS_ACL_KEXT_F_HALF_LOW + SYS_ACL_KEXT_F_HALF_HIGH
} sys_acl_kext_f_half_flag_t;


typedef enum sys_acl_kext_attr_s {
    SYS_ACL_KEXT_MULTI_GRAN = 0,
    SYS_ACL_KEXT_ATTR_PASS_THRU,
    SYS_ACL_KEXT_ATTR_NOT_WITH_QSET_UPDATE,
    SYS_ACL_KEXT_ATTR_COUNT
} sys_acl_kext_attr_t;

typedef struct sys_acl_kext_attrs_s {
    uint32 w[CTC_B2W_SIZE(SYS_ACL_KEXT_ATTR_COUNT)];
} sys_acl_kext_attrs_t;

typedef enum sys_acl_kext_sec_e {
    SYS_ACL_KEXT_SECTION_DISABLE = 0,
    SYS_ACL_KEXT_SECTION_L1E32,
    SYS_ACL_KEXT_SECTION_L1E16,
    SYS_ACL_KEXT_SECTION_L1E8,
    SYS_ACL_KEXT_SECTION_L1E4,
    SYS_ACL_KEXT_SECTION_L1E2,
    SYS_ACL_KEXT_SECTION_L2S1,
    SYS_ACL_KEXT_SECTION_L2S2,
    SYS_ACL_KEXT_SECTION_L3S1,
    SYS_ACL_KEXT_SECTION_L3S2,
    SYS_ACL_KEXT_SECTION_L2AS1,
    SYS_ACL_KEXT_SECTION_L2AS2,
    SYS_ACL_KEXT_SECTION_L2BS1,
    SYS_ACL_KEXT_SECTION_L2BS2,
    SYS_ACL_KEXT_SECTION_L2CS1,
    SYS_ACL_KEXT_SECTION_L2CS2,
    SYS_ACL_KEXT_SECTION_L3AS1,
    SYS_ACL_KEXT_SECTION_L3AS2,
    SYS_ACL_KEXT_SECTION_L3BS1,
    SYS_ACL_KEXT_SECTION_L3BS2,
    SYS_ACL_KEXT_SECTION_L3CS1,
    SYS_ACL_KEXT_SECTION_L3CS2,
    SYS_ACL_KEXT_SECTION_FK,
    SYS_ACL_KEXT_SECTION_FKA,
    SYS_ACL_KEXT_SECTION_FKB,
    SYS_ACL_KEXT_SECTION_FKC,
    SYS_ACL_KEXT_SECTION_COUNT
} sys_acl_kext_sec_t;

/* extractor control information */
typedef struct sys_acl_kext_ctrl_sel_info_s {
    sys_acl_kext_ctrl_sel_t ctrl_sel;
    uint8 ctrl_sel_val;
    uint8 part;
    uint8 level;
    uint8 gran;
    uint8 ext_num;
} sys_acl_kext_ctrl_sel_info_t;


/* Single extractor configuration. */
typedef struct sys_acl_kext_cfg_s {
    uint8  in_use;
    /* Extractor Id which holds 4 tuple (part, level, granularity, extractor number)
     * information of an extractor.
     * 10 bits[0 - 9]  = entractor number.
     * 8 bits[10 - 17] = granularity.
     * 4 bits[18 - 21] = hierarchy level.
     * 2 bits[29 - 31] = part(If extractor database is for multi wide modes).
     */
    uint32 ext_id;
    sys_acl_kext_sec_t in_sec;
    sys_acl_kext_sec_t out_sec;
    uint16 offset;
    sys_acl_kext_attrs_t ext_attrs;
    void *finfo;
    void *finfo1;
} sys_acl_kext_cfg_t;

typedef struct sys_acl_kext_sec_cfg_s
{
    uint32 flags;
    sys_acl_kext_sec_t sec;
    sys_acl_kext_sec_t parent_sec;
    int32 drain_bits;
    int32 fill_bits;
}
sys_acl_kext_sec_cfg_t;


typedef struct sys_acl_kext_cfg_db_s {
    uint8 num_ext_levels;
    sys_acl_keygen_mode_t mode;
    sys_acl_kext_cfg_t *ext_cfg[SYS_ACL_KEXT_LEVEL_COUNT];
    uint16 conf_size[SYS_ACL_KEXT_LEVEL_COUNT];
    sys_acl_kext_sec_cfg_t *sec_cfg[SYS_ACL_KEXT_SECTION_COUNT];
    uint16 num_sec;
} sys_acl_kext_cfg_db_t;

/* ------------------- Ext id ------------------ */
/* | 1098 | 7654321098 | 76543210 | 9876543210 | */
/* | PART |      LEVEL |     GRAN |        NUM | */
#define SYS_ACL_KEXT_ID_CREATE(_p_, _l_, _g_, _e_num_, _e_id_)              \
    (_e_id_) = (((_p_) << 28) |  ((_l_) << 18) | ((_g_) << 10)  |  (_e_num_))

#define SYS_ACL_KEXT_ID_PARSE(_e_id_, _p_, _l_, _g_, _e_num_)      \
                                (_e_num_) = ((_e_id_) & 0x3ff);       \
                                (_g_) = (((_e_id_) >> 10) & 0xff);    \
                                (_l_) = (((_e_id_) >> 18) & 0xf);     \
                                (_p_) = (((_e_id_) >> 28) & 0x3)

#define SYS_ACL_KEXT_ID_PART_GET(_ext_id_)  (((_ext_id_) >> 28) & 0x3)
#define SYS_ACL_KEXT_ID_GRAN_GET(_ext_id_)  (((_ext_id_) >> 10) & 0xff)
#define SYS_ACL_KEXT_ID_LEVEL_GET(_ext_id_) (((_ext_id_) >> 18) & 0xf)
#define SYS_ACL_KEXT_ID_NUM_GET(_ext_id_)   ((_ext_id_) & 0x3ff)

/* SYS_ACL_KEXT_CFG_ADD macro needs the following declaration
 * in any function that uses it.
 */
#define SYS_ACL_KEXT_CFG_DECL            \
    int32 _rv_;                               \
    int32 _ext_id_ = 0;                       \
    sys_acl_kext_cfg_t _ext_cfg_

/*
 * Extractor hierarcy construction utility macro.
 */
#define EXT_DB_ADD(_unit_, _ext_cfg_db_,                          \
                                _p_, _l_, _g_, _e_num_,                        \
                                _in_sec_, _out_sec_,                           \
                                _offset_, _ext_attrs_)                         \
            do {                                                               \
                _rv_ = sys_acl_kext_cfg_t_init(_unit_, &_ext_cfg_);           \
                if (STS_ACL_FAILURE(_rv_)) {                               \
                    STS_ACL_RETURN_VAL_EXIT(_rv_);                         \
                }                                                              \
                SYS_ACL_KEXT_ID_CREATE(_p_, _l_, _g_, _e_num_, _ext_id_);   \
                (_ext_cfg_).ext_id = (_ext_id_);                               \
                (_ext_cfg_).in_sec = (_in_sec_);                               \
                (_ext_cfg_).out_sec = (_out_sec_);                             \
                (_ext_cfg_).in_use = 0;                                        \
                (_ext_cfg_).offset = (_offset_);                               \
                sal_memcpy(&((_ext_cfg_).ext_attrs),                           \
                           (_ext_attrs_),                                      \
                           sizeof(sys_acl_kext_attrs_t));                   \
                _rv_ = sys_acl_kext_cfg_insert((_unit_), (_l_),             \
                                         &(_ext_cfg_), (_ext_cfg_db_));        \
                if (STS_ACL_FAILURE(_rv_)) {                               \
                    STS_ACL_RETURN_VAL_EXIT(_rv_);                         \
                }                                                              \
            } while(0)

typedef enum sys_acl_kfield_flags_e {
    SYS_ACL_KFIELD_FLAGS_PMUX = 0,
    SYS_ACL_KFIELD_FLAGS_NOT_IN_SINGLE,
    SYS_ACL_KFIELD_FLAGS_NOT_IN_DBLINTRA,
    SYS_ACL_KFIELD_FLAGS_NOT_IN_EM,
    SYS_ACL_KFIELD_FLAGS_COUNT
} sys_acl_kfield_flags_t;

typedef struct sys_acl_kfield_flags_bmp_s {
    uint32 w[CTC_B2W_SIZE(SYS_ACL_KFIELD_FLAGS_COUNT)];
} sys_acl_kfield_flags_bmp_t;

typedef struct sys_acl_kfield_offset_cfg_s {
    sys_acl_kext_sec_t section;
    uint16 sec_val;
    uint16 width;
    uint16 offset;
    uint16 size;
} sys_acl_kfield_offset_cfg_t;


typedef struct sys_acl_kfield_cfg_s
{
    sys_acl_kfield_flags_bmp_t field_flags;
    sys_acl_kext_ctrl_sel_t pri_ctrl_sel;
    uint16 pri_ctrl_sel_val;
    sys_acl_kfield_offset_cfg_t e_params[SYS_ACL_KFIELD_MAX_CHUNKS];
    uint8 num_chunks;
    uint32 size;
    uint8 update_count;
    uint8 l2_type;
    uint8 l3_type;
    uint8 l4_type;
}
sys_acl_kfield_cfg_t;

typedef struct sys_acl_kfield_cfg_info_s
{
    sys_acl_field_t field;
    sys_acl_kfield_cfg_t *field_cfg_arr;
    uint8 num_field_cfg;
}
sys_acl_kfield_cfg_info_t;

typedef struct sys_acl_kfield_cfg_info_db_s
{
    int32 num_fields;
    sys_acl_kfield_cfg_info_t *field_cfg_info[SYS_ACL_FIELD_COUNT];
}
sys_acl_kfield_cfg_info_db_t;


#define SYS_ACL_KFIELD_CFG_DECL          \
    int32 _rv_;                              \
    sys_acl_kfield_cfg_t _field_cfg_


#define SYS_ACL_KFIELD_CFG_INIT(_unit_)                       \
    _rv_ = sys_acl_kfield_cfg_t_init(_unit_, &(_field_cfg_));  \
    if (STS_ACL_FAILURE(_rv_)) {                            \
        STS_ACL_RETURN_VAL_EXIT(_rv_);                      \
    }\

#define SYS_ACL_KFIELD_CFG_OFFSET_ADD(_index_,                           \
                                        _section_,                         \
                                        _sec_val_,                         \
                                        _offset_,                          \
                                        _width_)                           \
                (_field_cfg_).e_params[_index_].section      = (_section_); \
                (_field_cfg_).e_params[_index_].sec_val      = (_sec_val_); \
                (_field_cfg_).e_params[_index_].offset       = (_offset_);  \
                (_field_cfg_).e_params[_index_].width        = (_width_);   \
                (_field_cfg_).num_chunks++;


#define SYS_ACL_KFIELD_CFG_CTRL_SEL_ADD(_ctrl_sel_, _ctrl_sel_val_)   \
                (_field_cfg_).pri_ctrl_sel     = (_ctrl_sel_);           \
                (_field_cfg_).pri_ctrl_sel_val = (_ctrl_sel_val_);       \


#define SYS_ACL_KFIELD_CFG_INSERT(_unit_, _field_cfg_info_db_,        \
                                    _field_id_, _field_flags_)           \
                sal_memcpy(&((_field_cfg_).field_flags),                 \
                           &(_field_flags_),                            \
                           sizeof(sys_acl_kfield_flags_bmp_t));      \
                _rv_ = sys_acl_kfield_cfg_insert((_unit_),           \
                                             (_field_id_),              \
                                             &(_field_cfg_),            \
                                             (_field_cfg_info_db_));    \
                if (STS_ACL_FAILURE(_rv_)) {                       \
                    STS_ACL_RETURN_VAL_EXIT(_rv_);                 \
                }\




typedef enum sys_acl_field_flags_e {

    SYS_ACL_FIELD_FLAGS_PMUX = 0,
    SYS_ACL_FIELD_FLAGS_NOT_IN_SINGLE,
    SYS_ACL_FIELD_FLAGS_NOT_IN_DBLINTRA,
    SYS_ACL_FIELD_NO_EM_SUPPORT,
    SYS_ACL_FIELD_NO_IFP_SUPPORT,
    SYS_ACL_FIELD_FLAGS_COUNT
} sys_acl_field_flags_t;

typedef struct sys_acl_field_flags_bmp_s {
    uint32 w[CTC_B2W_SIZE(SYS_ACL_FIELD_FLAGS_COUNT)];
} sys_acl_field_flags_bmp_t;



typedef struct sys_acl_kset_s {
    uint32 w[CTC_B2W_SIZE(SYS_ACL_FIELD_COUNT)];
} sys_acl_kset_t;

enum sys_acl_fk_size_mode_e
{
    SYS_ACL_FK_SIZE_MODE_AUTO,
    SYS_ACL_FK_SIZE_MODE_SINGLE,
    SYS_ACL_FK_SIZE_MODE_DOUBLE,
    SYS_ACL_FK_SIZE_MODE_TRIPLE,
    SYS_ACL_FK_SIZE_MODE_COUNT
};
typedef enum sys_acl_fk_size_mode_e sys_acl_fk_size_mode_t;

#if 0
typedef struct sys_acl_flex_group_s
{
    uint8 mode;                       /* Group mode, refer to SYS_ACL_GROUP_MODE_XXX */
    uint8 key_type;                   /*ctc_acl_key_type_t*/
    uint8 ltid;                       /* Logic table ID */
    uint8 priority;                   /* Action priority */
    uint8 block_id;
    uint32 flags;                     /* Group create flags, refer to SYS_ACL_GROUP_SPAN_XXX*/
    sys_acl_kset_t kset;              /* Group fieldifier set. */
    ctc_acl_presel_set_t preselset;   /* Group preselector set */
    sys_acl_field_bitmap_t *field_bitmap; /* Qual field split in multi slice, [unuseful] */
    sys_acl_ext_sel_t ext_codes[SYS_ACL_ENTRY_PARTS_MAX];   /* Extract selector db */
    sys_acl_group_field_offset_info_t field_arr[SYS_ACL_ENTRY_PARTS_MAX];
    struct sys_acl_presel_s *presel_ent_arr[SYS_ACL_PRESEL_NUM];
}
sys_acl_flex_group_t;
#endif

#define SYS_ACL_FLEX_KEY_NODE_FIXED     0
#define SYS_ACL_FLEX_KEY_NODE_HASH      1
#define SYS_ACL_FLEX_KEY_NODE_I_TCAM    2
#define SYS_ACL_FLEX_KEY_NODE_E_TCAM    3
#define SYS_ACL_FK_IS_HASH(fk)          (SYS_ACL_FLEX_KEY_NODE_HASH == ACL_SHARE_PTR(fk, sys_acl_flex_hash_t)->node_type)
#define SYS_ACL_FK_FLAG_IS_IPV6         (1U << 15)

typedef struct
{
    uint32 presel_cnt;
    uint16* entry_count;
    struct sys_acl_presel_s *presel_ent_arr[SYS_ACL_PRESEL_NUM];
}sys_acl_fk_pp_t;

struct sys_acl_flex_key_s
{
    uint32 key_type             :8;
    uint32 node_type            :3;   /*refer to SYS_ACL_FLEX_KEY_NODE_XXX*/
    uint32 key_req_bits         :16;
    uint32 rsv                  :5;
    sys_acl_kset_t kset;

    uint8  key_size;                                /*refer to SYS_ACL_FK_SPAN_TRIPLE_SLICE*/
    uint8  ad_index;
    uint16 flags;

    uint32 lkup_type    :8;
    uint32 ltid_valid   :24;
    uint8  ltid[ACL_IGS_BLK_MAX_NUM];
    /*sys_acl_field_bitmap_t *field_bitmap;*/     /* Qual field split in multi slice */
    sys_acl_ext_sel_t ext_codes[SYS_ACL_ENTRY_PARTS_MAX];   /* Extract selector db */
    sys_acl_group_field_offset_info_t field_arr[SYS_ACL_ENTRY_PARTS_MAX];
    uint32 presel_cnt;
    uint16* entry_count;
    struct sys_acl_presel_s *presel_ent_arr[SYS_ACL_PRESEL_NUM];
    int8 xdata_sel[SYS_ACL_KEXT_XDATA_SEL_MAX];
};
typedef struct sys_acl_flex_key_s sys_acl_flex_key_t;

struct sys_acl_flex_hash_s
{
    uint32 key_type             :8;
    uint32 node_type            :3;
    uint32 key_size             :3;
    uint32 hash_type            :8;
    uint32 origin_key_type      :6;/* for flow hash 0 */
    uint32 mode                 :2;/* for flow hash 0 */
    uint32 rsv0                  :2;
    sys_acl_kset_t kset;

    uint32 udf_bmp              :8;
    uint32 rsv1                 :24;
    ctc_xdata_t* xdata;
    uint32 presel_cnt;
    uint16* entry_count;
    struct sys_acl_presel_s *presel_ent_arr[SYS_ACL_PRESEL_NUM];
};
typedef struct sys_acl_flex_hash_s sys_acl_flex_hash_t;

int32
sys_acl_kfield_cfg_t_init(int32 unit, sys_acl_kfield_cfg_t *field_cfg);

int32
sys_acl_kfield_cfg_insert(int32 unit,
                 uint32 field_id,
                 sys_acl_kfield_cfg_t *new_field_cfg,
                 sys_acl_kfield_cfg_info_db_t *field_cfg_info_db);


int32
sys_acl_kext_cfg_t_init(int32 unit, sys_acl_kext_cfg_t *ext_cfg);

int32
sys_acl_kext_cfg_insert(int32 unit,
                     uint8 level,
                     sys_acl_kext_cfg_t *ext_cfg,
                     sys_acl_kext_cfg_db_t *ext_cfg_db);

extern int32
sys_tmm_acl_extract_db_init(uint8 lchip);

extern void
sys_tmm_acl_extract_db_deinit(uint8 lchip);


//int32
//sys_acl_group_assign_sel_code(int32 unit, sys_acl_flex_group_t *fg);

int32
sys_tmm_acl_flex_key_assign_sel_code(uint8 lchip, uint8 size_mode, sys_acl_flex_key_t *p_flex_key);

#ifdef __cplusplus
}
#endif
#endif

